﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Baik.Interface.Expression;

namespace Baik.Interface.Execution
{

    public interface IVariable
    {
        IValueRecord ValueRecord { get; set; }
        string AsString();
    }
    public interface ILogged
    {
        IEnumerable<IValueLog> Log { get; }
    }
    public interface IValueRecord
    {
        void Assign(IVariable variable);
        void DeAssign(IVariable variable);
        IObject Value { get; set; }
    }
    public interface ICallStack
    {
        IEnumerable<IExpression> Stack { get; set; }
    }
    public interface IValueLog
    {
        DateTime OnDateTime { get; set; }
        IObject Before { get; set; }
        IObject After { get; set; }
        ICallStack Call { get; set; }
    }
    public interface IScope
    {
        IEnumerable<IScope> Parents { get; set; }
        IScope DeclarationScope { get; set; }
        bool TryGet(string name, out IObject val);
        string AsString();
        IObject Get(string name);
        IArray GetAllMembers();
        void Assign(string name, IObject value);
    }
    public interface IObject : IScope
    {
        string Name { get; set; }
        void Assign();
        void DeAssign();
        void Inherit(IObject parent);
    }
    public interface IFunction : IObject
    {
        IScope HostingScope { get; set; }
        IObject Call(IEnumerable<IObject> Params);
        IEnumerable<IReference> Params { get; set; }
        IEnumerable<IExpression> Expressions { get; set; }
    }
    public interface IBuiltInFunction : IFunction
    {
        Func< IEnumerable<IObject>, IObject> Method { get; set; }
    }
    public interface IFunctionFunction : IObject
    {
        //this is designed to hos the Statistics and other features of functions;
    }
    public interface IArray : IObject
    {
        IEnumerable<IObject> Items { get; set; }

        IObject GetByIndex(double index);
        

        void Add(IObject obj);
    }
    public interface IString : IObject
    {
        string Value { get; set; }
    }
    public interface INumber : IObject
    {
        double Value { get; set; }
    }
    public interface IBoolean : IObject
    {
        bool Value { get; set; }
    }
    public interface ITrue : IBoolean
    {
        
    }
    public interface IFalse : IBoolean
    {
        
    }
    public interface IUndefined : IObject
    {
        
    }
    public interface IProgram : IObject
    {
        IFunction Start { get; set; }
        IValueRecord Get(IObject obj);
        IObject Execute();
    }
    public interface IExecutionEnvironment
    {
        IEnumerable<string> Eval(IEnumerable<IExpression> exps);
        IObject Eval(IExpression exp);
        IObject Eval(string code);
        IObject Load(string filepath);
        IExpression Parse(string code);
        void Refresh();
    }
    public interface ISystem : IObject
    {
        
    }

    public interface IExceptionHost 
    {
        IObject Exception { get; set; }
    }

    public interface IExceptionThrower
    {
        void Throw(string msg);
        void Throw(IObject obj);
    }
}
